﻿/*******************************************************************************

  NLocalizer (C) 2010-2012 Chris Prusik (KAP1 Ltd www.kap1.net)
  The fast, simple solution for localizing .NET applications, by text files.
  Latest version: http://NLocalizer.codeplex.com/

  $Id$

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

*******************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace NLocalizer
{
    /// <summary>
    /// Helper which write language files into application directory
    /// </summary>
    public static class LangWriter
    {
        /// <summary>
        /// Create string builder from the specified translation.
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="translation">The translation.</param>
        /// <returns></returns>
        public static StringBuilder ToStringBuilder(string language, Translation translation)
        {
            StringBuilder str = new StringBuilder();
            str.AppendLine("; NLocalizer (C) Chris Prusik (KAP1 Ltd www.kap1.net), NLocalizer.codeplex.com");
            str.AppendLine(String.Format("; Language file: {0}, autogenerated {1}",
                language, DateTime.Now.ToShortDateString()));
            str.AppendLine("; $Id" + "$");
            str.AppendLine(";");
            str.AppendLine("; !(ClassName)StaticPropertyName = translated message");
            str.AppendLine("; (ClassName)DynamicPropertyName = translated message");
            str.AppendLine("; module FileName1.dll, FileName2.dll");
            str.AppendLine("; using Namespace1, Namespace2");
            str.AppendLine("; static StaticClassName1, StaticClassName2");
            str.AppendLine("; template file.tpl");
            str.AppendLine("; debug file.cs");
            str.AppendLine("; log file.log");
            str.AppendLine(";");

            string textLocales = "";
            foreach (KeyValuePair<string, string> localeItem in translation.Locales)
                if (localeItem.Value == language)
                    textLocales += localeItem.Key + ", ";
            if (textLocales != "")
                str.AppendLine("locale " + textLocales.Remove(textLocales.Length - 2));

            if (translation.CodeDlls.Count > 0)
            {
                string text = "";
                foreach (string moduleItem in translation.CodeDlls)
                    text += moduleItem + ", ";
                str.AppendLine("module " + text.Remove(text.Length - 2));
            }

            if (translation.CodeUsings.Count > 0)
            {
                string text = "";
                foreach (string usingItem in translation.CodeUsings)
                    text += usingItem + ", ";
                str.AppendLine("using " + text.Remove(text.Length - 2));
            }

            if (translation.StaticClasses.Count > 0)
            {
                string text = "";
                foreach (string staticItem in translation.StaticClasses)
                    text += staticItem + ", ";
                str.AppendLine("static " + text.Remove(text.Length - 2));
            }

            if (translation.Exists(language))
                foreach (KeyValuePair<string, TranslationProperties> classItem in translation[language])
                    foreach (KeyValuePair<string, TranslationProperty> propertyItem in classItem.Value)
                    {
                        string modifier = "";
                        if (propertyItem.Value.IsStatic)
                            modifier = "!";
                        str.AppendLine(String.Format("{0}({1}){2} = {3}",
                            modifier, classItem.Key, propertyItem.Key,
                            ReplaceSpecialChars(propertyItem.Value.Message)));
                    }
            return str;
        }

        /// <summary>
        /// Replace special chars \r \n \t \\ \"
        /// </summary>
        /// <param name="message">input text</param>
        /// <returns></returns>
        public static string ReplaceSpecialChars(string message)
        {
            List<string> macros = Macro.GetMacros(message);
            message = Macro.NamesToNumbers(message, macros);
            message = message.Replace("\\", @"\\").
                Replace("\r", @"\r").
                Replace("\n", @"\n").
                Replace("\t", @"\t").
                Replace("\"", "\\\"");
            message = Macro.NumbersToNames(message, macros);
            return message;
        }

        /// <summary>
        /// Write the specified language from translation into the directory name.
        /// </summary>
        /// <param name="directoryName">Name of the directory.</param>
        /// <param name="language">The language.</param>
        /// <param name="translation">The translation.</param>
        public static void Write(string directoryName, string language, Translation translation)
        {
            File.WriteAllText(Path.Combine(directoryName, language + ".lang"),
                ToStringBuilder(language, translation).ToString());
        }

        /// <summary>
        /// Write the specified translation into file in directory.
        /// </summary>
        /// <param name="directoryName">Name of the directory.</param>
        /// <param name="translation">The translation.</param>
        public static void Write(string directoryName, Translation translation)
        {
            foreach (KeyValuePair<string, TranslationClasses> languageItem in translation)
                if (languageItem.Key != "Neutral")
                    Write(directoryName, languageItem.Key, translation);
        }

        /// <summary>
        /// Write all the specified translation into files in the application directory.
        /// </summary>
        /// <param name="translation">The translation.</param>
        public static void Write(Translation translation)
        {
            Write(Path.GetDirectoryName(Application.ExecutablePath), translation);
        }

    }
}